package archer.application.core.service.user;

import archer.application.core.constant.Constant;
import archer.application.core.entity.user.User;
import archer.application.core.service.BaseService;
import archer.application.core.subject.ArcherUser;
import archer.framework.protocol.result.ExecuteResult;
import archer.framework.security.token.Token;
import archer.framework.security.utils.SubjectUtils;
import org.springframework.stereotype.Component;

/**
 * 用户父类Service
 *
 * @author christ
 * @date 2016/6/3
 */
@Component
public class UserService extends BaseService {

    /**
     * 手机号是否已被注册
     *
     * @param mobile
     * @param type
     * @return
     */
    public ExecuteResult mobileRegistered(String mobile, String type) {

        if (isEmpty(mobile) || isEmpty(type)) {
            throwParamNullException();
        }

        User user = User.find
                .query()
                .where()
                .eq("mobile", mobile)
                .eq("type", type)
                .findUnique();

        if (isNotEmpty(user)) {
            return resultTrue().setResultMsg("该手机号已注册");
        }

        return resultFalse();
    }

    public ExecuteResult loginNameRegistered(String loginName, String type) {

        if (isEmpty(loginName) || isEmpty(type)) {
            throwParamNullException();
        }

        User user = User.find
                .query()
                .where()
                .eq("loginName", loginName)
                .eq("type", type)
                .findUnique();

        if (isNotEmpty(user)) {
            return resultTrue().setResultMsg("该登录用户已注册");
        }

        return resultFalse();
    }

    public ExecuteResult emailRegistered(String email, String type) {

        if (isEmpty(email) || isEmpty(type)) {
            throwParamNullException();
        }

        User user = User.find
                .query()
                .where()
                .eq("email", email)
                .eq("type", type)
                .findUnique();

        if (isNotEmpty(user)) {
            return resultTrue().setResultMsg("该邮箱已注册");
        }

        return resultFalse();
    }

    /**
     * 用手机号登录
     *
     * @param mobile
     * @param password
     * @param type
     * @return
     */
    public ExecuteResult mobileLogin(String mobile, String password, String type) {

        return login(mobile, null, null, password, type);
    }

    /**
     * 用登录用户名登录
     *
     * @param loginName
     * @param password
     * @param type
     * @return
     */
    public ExecuteResult loginNameLogin(String loginName, String password, String type) {

        return login(null, loginName, null, password, type);
    }

    /**
     * 登录
     *
     * @param mobile
     * @param password
     * @param type
     * @return
     */
    public ExecuteResult login(String mobile, String loginName, String email, String password, String type) {

        if (isEmpty(password)) {
            throwParamNullException("密码不能为空");
        }

        if (isEmpty(type)) {
            throwParamNullException("用户类型不能为空");
        }

        if (isEmpty(mobile) && isEmpty(loginName) && isEmpty(email)) {
            // 最少三选一
            throwParamNullException("用户凭证不能为空");
        }

        User user = null;
        // 根据手机号查
        if (isNotEmpty(mobile)) {
            user = User.find
                    .query()
                    .where()
                    .eq("mobile", mobile)
                    .eq("password", password)
                    .eq("type", type)
                    .findUnique();
        }

        if (isEmpty(user) && isNotEmpty(loginName)) {
            user = User.find
                    .query()
                    .where()
                    .eq("loginName", loginName)
                    .eq("password", password)
                    .eq("type", type)
                    .findUnique();
        }

        if (isEmpty(user) && isNotEmpty(email)) {
            user = User.find
                    .query()
                    .where()
                    .eq("email", email)
                    .eq("password", password)
                    .eq("type", type)
                    .findUnique();
        }

        if (isEmpty(user)) {
            throwParamInvalidateException("用户名或密码错误");
        }

        if (Constant.UserStatus.DISABLE.equals(user.getStatus())) {
            throwAccessDeniedException("当前用户已被禁用");
        }

        // token 处理
        ArcherUser archerUser = new ArcherUser()
                .setUserId(user.getId())
                .setLoginName(user.getLoginName())
                .setEmail(user.getEmail())
                .setMobile(user.getMobile())
                .setType(user.getType());

        Token token = SubjectUtils.bindAssociatedToken(archerUser);

        // 记录用户最近一次登录时间
        user.setLastLoginTime(now().getTimestamp()).store();

        return success(asMap(
                "token", token.getId(),
                "userId", user.getId(),
                "loginName", user.getLoginName()
        ));
    }

    /**
     * 退出
     *
     * @return
     */
    public ExecuteResult logout() {

        SubjectUtils.invalidateAssociatedToken();

        return success();
    }

    /**
     * 修改用户登录名
     *
     * @param id
     * @param loginName
     * @param type
     * @return
     */
    public ExecuteResult changeLoginName(String id, String loginName, String type) {

        if (isEmpty(id)) {
            throwParamNullException("用户不能为空");
        }

        if (isEmpty(loginName)) {
            throwParamNullException("用户名不能为空");
        }

        if (loginName.length() < 3 || loginName.length() > 30) {
            throwParamNullException("用户名长度为3-30个字符");
        }

        if (isEmpty(type)) {
            throwParamNullException("用户类型不能为空");
        }

        User user = User.find.query()
                .where()
                .eq("id", id)
                .findUnique();

        if (user.setLoginName(loginName).duplicated("loginName", asMap("type", type))) {
            throwParamInvalidateException("该用户名已存在");
        }

        ArcherUser archerUser = getCurrentUser();
        if (isNotEmpty(archerUser)) {
            SubjectUtils.updateSubject(archerUser.setLoginName(loginName));
        }

        user.store();

        return success();
    }

    /**
     * 修改手机号
     *
     * @param id
     * @param mobile
     * @param type
     * @return
     */
    public ExecuteResult changeMobile(String id, String mobile, String type) {

        if (isEmpty(id)) {
            throwParamNullException("用户不能为空");
        }

        if (isEmpty(type)) {
            throwParamNullException("用户类型不能为空");
        }

        if (isEmpty(mobile) || isNotMoblie(mobile)) {
            throwParamInvalidateException("手机号格式不正确");
        }

        User user = User.find.query()
                .where()
                .eq("id", id)
                .findUnique();

        if (user.setMobile(mobile).duplicated("loginName", asMap("type", type))) {
            throwParamInvalidateException("该手机号已注册");
        }

        ArcherUser archerUser = getCurrentUser();
        if (isNotEmpty(archerUser)) {
            SubjectUtils.updateSubject(archerUser.setMobile(mobile));
        }

        user.store();

        return success();
    }

    /**
     * 修改密码
     *
     * @param id
     * @param oldPassword
     * @param newPassword
     * @return
     */
    public ExecuteResult changePassword(String id, String oldPassword, String newPassword) {

        if (isEmpty(id)) {
            throwParamNullException("用户不能为空");
        }

        if (isEmpty(oldPassword)) {
            throwParamNullException("旧密码不能为空");
        }

        if (isEmpty(newPassword)) {
            throwParamNullException("新密码不能为空");
        }

        User user = User.find
                .query()
                .where()
                .eq("id", id)
                .eq("password", oldPassword)
                .findUnique();

        if (isEmpty(user)) {
            throwParamInvalidateException("旧密码错误");
        }

        user.setPassword(newPassword).store();

        return success();
    }

    /**
     * 直接更新密码
     *
     * @param id
     * @param password
     * @return
     */
    public ExecuteResult updatePassword(String id, String password) {

        if (isEmpty(id)) {
            throwNotLoginedException("请先登录");
        }

        if (isEmpty(password)) {
            throwParamNullException("密码不能为空");
        }

        User user = User.find.byId(id);

        if (isNotEmpty(user)) {
            user.setPassword(password).store();
        }

        return success();
    }
}
